/**
 * Created by zhanglihe on 15/12/31.
 * --------------------------------------------------------------------------------
 *  表单验证类
 * --------------------------------------------------------------------------------
 *      使用示例：
 *      var validation = new Validation({
 *          rules: {
                        username: {required: true, email: true},
                        rebate1: {int: true, maxInt: 100, minInt: 1},
                        password: {required: true, minLength: 6, maxLength: 32},
                        ......
                    }
 *      });
 *
 *      在表单提交前判断验证是否通过：
 *          if(validation.isFail()) {
 *              //取消表单提交
 *          }
 *
 */
require.config(require_config);

define([
    'jquery'
], function ($) {
    var Validation = function(options) {
        var defaults = {
            dataSource: 'form', //数据源:form表单或...留待扩展
            rules: {}
        };
        var originalOptions = options = options || {};
        options = $.extend(true, {}, defaults, options);
        options.original = originalOptions;

        $.extend(this, options);
        this.initialize();
        return this;
    };

    Validation.prototype = {
        initialize: function() {
            this.ready();
        },

        messages: {
            required: '这里一定要填的(别这么懒好吧)',
            int: '这里只能填整数哦',
            email: '这不是有效的邮箱吧(我读书多别想骗我)',
            number: '这里只能填数字哦',
            float: '这里只能填带小数点的数字呢',
            mobile: '这好像不是一个有效的手机号码',
            minLength: '长度不能小于{0}',
            maxLength: '长度不能超过{0}',
            minInt: '最大值不能小于{0}',
            maxInt: '最大值不能超过{0}',
            minFloat: '最大值不能小于{0}',
            maxFloat: '最大值不能超过{0}'
        },

        accord: {
            required: 'notEmpty',
            int: 'isInt',
            email: 'isEmail',
            number: 'isNumber',
            float: 'isFloat',
            mobile: 'isMobile',
            minLength: 'minLength',
            maxLength: 'maxLength',
            minInt: 'minInt',
            maxInt: 'maxInt',
            minFloat: 'minFloat',
            maxFloat: 'maxFloat'
        },

        rules: {
            //name: {required: true, email: true}
        },

        failed: false,

        errors: {},

        isFail: function() {
            this.failed = false;
            this.check();
            console.log(this.failed);
            return this.failed;
        },

        ready: function() {
            for(var n in this.rules) {
                this.bindEvent(n);
            }
        },

        bindEvent: function(name) {
            var _this = this;
            $('[name="' + name + '"]').on('change', function () {
                _this.checkOne(name);
            });
        },

        check: function() {
            for(var n in this.rules) {
                this.checkOne(n);
            }
        },

        checkOne: function(name) {
            var rule = this.rules[name];
            if(typeof rule === 'function') {
                return rule(this);
            }
            for(var accord in rule) {
                if(this.dataSource == 'form') {
                    if(this[this.accord[accord]]($('[name="'+name+'"]').val(), rule[accord])) {
                        this.valid(name);
                        continue;
                    }
                    this.invalid(name, accord);
                    break;
                }
            }
        },

        invalid: function (name, accord) {
            console.log(name, 'invalid');
            this.failed = true;
            var dom = $('[name="' + name + '"]');
            if (dom.parent().hasClass('has-error')) {
                return;
            }
            this.showMessage(name, accord);
        },

        valid: function(name) {
            $('[name="' + name + '"]').parent().removeClass('has-error').find('.error-msg').remove();
        },

        getMessage: function (name, accord) {
            var msg = $('[name="' + name + '"]').attr("data-error-msg");
            if (typeof(msg) !== "undefined") {
                return msg;
            }
            if(typeof this.messages[accord] !== 'undefined') {
                return this.messages[accord].replace('{0}', this.rules[name][accord]);
            }
            return '格式错误';
        },

        showMessage: function(name, accord) {
            $('[name="' + name + '"]').parent().addClass('has-error')
                .append('<span class="label label-warning error-msg">'
                + this.getMessage(name, accord) + '</span>');
        },

        notEmpty: function(val, result) {
            return !( !val || val == '' || val === undefined || val === null) === result;
        },
        isEmail: function(val, result) {
            return val == '' || /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/i.test(val) === result;
        },
        isNumber: function(val, result) {
            return val == '' || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(val) === result;
        },
        isInt: function(val, result) {
            return val == '' || /^(\d+)$/.test(val) === result;
        },
        isFloat: function(val, result) {
            return val == '' || /^(\d+)(\.\d+)$/.test(val) === result;
        },
        isMobile: function(val, result) {

            return val == '' || /^(13[0-9]|14[0-9]|15[0-9]|17[0-9]|18[0-9])\d{8}$/.test(val) === result;
        },
        minLength: function(val, len) {
            return val == '' || val.length >= len;
        },
        maxLength: function(val, len) {
            return val == '' || val.length <= len;
        },
        minInt: function(val, result) {
            return val == '' || parseInt(val) >= result;
        },
        maxInt: function(val, result) {
            return val == '' || parseInt(val) <= result;
        },
        minFloat: function(val, result) {
            return val == '' || parseFloat(val) >= result;
        },
        maxFloat: function(val, result) {
            return val == '' || parseFloat(val) <= result;
        }

    };

    return Validation;
});
